<script setup lang="ts">
import { computed, nextTick, reactive, ref, useTemplateRef } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { Delete, Edit, Female, Male } from "@element-plus/icons-vue";
import { NetState, Operation, isMobile } from "@/utils/utils.ts";
import { getClassList } from "@/api/classes";
import {
  addStudentApi,
  batchExcelStudentApi,
  batchStudentApi,
  delStudentApi,
  getStudentListApi,
  updateStudentApi
} from "@/api/student";
import { cloneDeep } from "@pureadmin/utils";
import dayjs from "dayjs";
import TextImport from "@/views/student-manage/components/TextImport.vue";
import ExcelImport from "@/views/student-manage/components/excelImport.vue";

const classList = ref([]);
const studentList = ref([]);
const dialogVisible = ref(false);
const submitLoading = ref(false);
const editFormRef = useTemplateRef("editFormRef");
const curOperate = ref(Operation.Create);
const curClass = ref();
const multipleSelection = ref([]);
const stuTotal = ref(0);
const addDisabled = computed(() => {
  return !curClass.value;
});
const batchDelDisable = computed(() => {
  return !multipleSelection.value.length;
});
const dialogTitle = computed(() => {
  return curOperate.value === Operation.Create ? "添加学生" : "修改学生";
});
const originEditForm = {
  class_id: "",
  stu_name: "",
  stu_number: "",
  grade: "",
  birthday: "",
  sex: 0,
  phone: "",
  email: "",
  address: ""
};
const editForm = ref({ ...cloneDeep(originEditForm) });

const validatePhone = function (rule, value, callback) {
  if (!value || /^\s*$/.test(value)) {
    return callback();
  }
  if (!/^1[3-9]\d{9}$/.test(value)) {
    callback(new Error("电话格式错误"));
  }

  callback();
};
const validateEmail = function (rule, value, callback) {
  if (!value || /^\s*$/.test(value)) {
    return callback();
  }
  if (
    !/^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/.test(
      value
    )
  ) {
    callback(new Error("邮箱格式错误"));
  }

  callback();
};
const editFormRules = reactive({
  stu_name: [
    { required: true, message: "请输入学生名称", trigger: "blur" },
    { max: 50, message: "最多50个字符", trigger: "blur" }
  ],
  stu_number: [{ max: 20, message: "最多20个字符", trigger: "blur" }],
  grade: [{ max: 20, message: "最多20个字符", trigger: "blur" }],
  phone: [{ validator: validatePhone, trigger: "blur" }],
  email: [{ validator: validateEmail, trigger: "blur" }],
  address: [{ message: "最多100个字符", trigger: "blur" }]
});
const openDialog = async function (operate: Operation, row?: object) {
  await nextTick();
  editFormRef.value?.clearValidate();
  curOperate.value = operate;
  editForm.value =
    operate === Operation.Create ? cloneDeep(originEditForm) : cloneDeep(row);
  editForm.value.class_id = curClass.value.class_id;
  editForm.value.sex =
    typeof editForm.value.sex !== "number" ? 0 : editForm.value.sex;
  dialogVisible.value = true;
};
const submitHandle = async function () {
  await editFormRef.value.validate(valid => {
    if (!valid) return;
    const param = {
      ...editForm.value
    };
    submitLoading.value = true;
    const api = {
      [Operation.Create]: addStudentApi,
      [Operation.Update]: updateStudentApi
    };
    api[curOperate.value]?.(param)
      .then(res => {
        if (res.code === NetState.Success) {
          const msg =
            curOperate.value === Operation.Create
              ? "添加学生成功"
              : "修改学生成功";
          ElMessage.success(msg);
          dialogVisible.value = false;
          getStudentList();
        }
        submitLoading.value = false;
      })
      .catch(() => {
        submitLoading.value = false;
      });
  });
};

const getClassesList = async function () {
  const result = await getClassList();
  const list = result.data ?? [];
  classList.value = list;
  curClass.value = list[0];
  editForm.value.class_id = curClass.value.class_id;
  getStudentList();
};

const getStudentList = async function () {
  if (!curClass.value) return;
  const param = {
    class_id: curClass.value.class_id
  };
  const { data } = await getStudentListApi(param);
  const list = data.list ?? [];

  list.forEach(item => {
    item.create_time = dayjs(item.create_time).format("YYYY-MM-DD hh:mm");
    if (item.birthday) {
      item.age = dayjs(Date.now()).diff(item.birthday, "year");
    }
  });
  studentList.value = list;
  stuTotal.value = data.total || 0;
};

getClassesList();

const delStudent = function (item) {
  ElMessageBox.confirm(`确认删除？`, {
    title: "确认删除",
    type: "warning"
  })
    .then(() => {
      const params = {
        stu_id_list: [item.stu_id]
      };
      return delStudentApi(params);
    })
    .then(res => {
      if (res.code === NetState.Success) {
        ElMessage.success(`删除成功`);
        getStudentList();
      }
    });
};

const changeClass = function () {
  getStudentList();
};

const handleSelectionChange = function (val) {
  multipleSelection.value = val;
};

const batchDelStudent = function () {
  ElMessageBox.confirm(`确认批量删除？`, {
    title: "确认删除",
    type: "warning"
  })
    .then(() => {
      const params = {
        stu_id_list: multipleSelection.value.map(item => item.stu_id)
      };
      return delStudentApi(params);
    })
    .then(res => {
      if (res.code === NetState.Success) {
        ElMessage.success(`批量删除成功`);
        getStudentList();
      }
    });
};

// 文本导入
const textImportVisible = ref(false);
const openTextImport = function (visible = true) {
  textImportVisible.value = visible;
};
const textImportSubmit = function ({ class_id, data }) {
  const params = {
    class_id,
    stu_list: data.map(text => ({ stu_name: text }))
  };
  batchStudentApi(params).then(res => {
    if (res.code === NetState.Success) {
      ElMessage.success("文本导入成功");
      getStudentList();
      openTextImport(false);
    }
  });
};

// excel 导入
const excelImportVisible = ref(false);
const openExcelImport = function (visible = false) {
  excelImportVisible.value = visible;
};
const excelImportSubmit = function (data) {
  const param = {
    stu_list: data
  };
  batchExcelStudentApi(param).then(res => {
    if (res.code === NetState.Success) {
      ElMessage.success("Excel 导入成功");
      getClassesList();
      openExcelImport(false);
    }
  });
};
</script>

<template>
  <div class="page-container">
    <div class="class-box">
      <span class="title">学生{{ stuTotal }}，当前班级</span>
      <ElSelect
        v-model="curClass"
        class="class-select"
        value-key="class_id"
        placeholder="暂无班级"
        @change="changeClass"
      >
        <ElOption
          v-for="item in classList"
          :key="item.class_id"
          :label="item.class_name"
          :value="item"
        />
      </ElSelect>
      <ElButton
        type="primary"
        :disabled="addDisabled"
        @click="openDialog(Operation.Create)"
        >添加学生</ElButton
      >
      <ElButton
        type="primary"
        :disabled="addDisabled"
        @click="openTextImport(true)"
        >文本导入</ElButton
      >
      <ElButton type="primary" @click="openExcelImport(true)"
        >Excel导入</ElButton
      >
      <ElButton
        type="danger"
        :disabled="batchDelDisable"
        @click="batchDelStudent"
        >批量删除</ElButton
      >
    </div>

    <div class="table-box">
      <ElTable
        :data="studentList"
        row-key="stu_id"
        @selection-change="handleSelectionChange"
      >
        <ElTableColumn type="selection" width="30" />
        <ElTableColumn
          label="学生姓名"
          prop="stu_name"
          min-width="140"
          fixed="left"
        >
          <template #default="{ row }">
            <div class="stu-name">
              <ElIcon v-if="row.sex === 1" class="icon male"><Male /></ElIcon>
              <ElIcon v-if="row.sex === 2" class="icon female"
                ><Female
              /></ElIcon>
              <span>{{ row.stu_name }}</span>
            </div>
          </template>
        </ElTableColumn>
        <ElTableColumn label="缺勤次数" prop="absent_count" />
        <ElTableColumn label="学号" prop="stu_number" show-overflow-tooltip />
        <ElTableColumn label="年级" prop="grade" />
        <ElTableColumn label="年龄" prop="age" />
        <ElTableColumn label="电话" prop="phone" show-overflow-tooltip />
        <ElTableColumn label="邮箱" prop="email" show-overflow-tooltip />
        <ElTableColumn label="住址" prop="address" show-overflow-tooltip />
        <ElTableColumn label="创建时间" prop="create_time" min-width="150" />
        <ElTableColumn label="操作" width="70" align="center" fixed="right">
          <template #default="{ row }">
            <ElButton
              class="btn"
              :icon="Edit"
              @click="openDialog(Operation.Update, row)"
              text
            ></ElButton>
            <ElButton
              class="btn"
              :icon="Delete"
              @click="delStudent(row)"
              text
            ></ElButton>
          </template>
        </ElTableColumn>
        <template #empty>
          <ElEmpty description="暂无学生数据">
            <template #default>
              <div v-if="addDisabled" class="tips">
                当前暂无班级，请
                <router-link class="add-class" to="/class-manage"
                  >添加班级</router-link
                >
                后再“添加学生”和“文本批量导入”，也可直接通过 excel 导入
              </div>
            </template>
          </ElEmpty>
        </template>
      </ElTable>
    </div>

    <ElDialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="520"
      :close-on-click-modal="false"
      :fullscreen="isMobile()"
    >
      <div class="dialog-form">
        <ElForm
          ref="editFormRef"
          :model="editForm"
          :rules="editFormRules"
          label-width="80"
        >
          <ElFormItem label="所属班级">
            <ElSelect
              v-model="editForm.class_id"
              class="class-select"
              placeholder="请选择班级"
            >
              <ElOption
                v-for="item in classList"
                :key="item.class_id"
                :label="item.class_name"
                :value="item.class_id"
              />
            </ElSelect>
          </ElFormItem>
          <ElFormItem label="学生名称" prop="stu_name">
            <ElInput
              v-model.trim="editForm.stu_name"
              placeholder="请输入学生名称"
            />
          </ElFormItem>
          <ElFormItem label="学号" prop="stu_number">
            <ElInput
              v-model.trim="editForm.stu_number"
              placeholder="请输入学号"
            />
          </ElFormItem>
          <ElFormItem label="年级" prop="grade">
            <ElInput v-model.trim="editForm.grade" placeholder="请输入年级" />
          </ElFormItem>
          <ElFormItem label="性别">
            <ElRadioGroup v-model="editForm.sex">
              <ElRadio :value="0">保密</ElRadio>
              <ElRadio :value="1">男</ElRadio>
              <ElRadio :value="2">女</ElRadio>
            </ElRadioGroup>
          </ElFormItem>
          <ElFormItem label="生日">
            <ElDatePicker
              v-model="editForm.birthday"
              type="date"
              placeholder="请选择生日"
            />
          </ElFormItem>
          <ElFormItem label="电话" prop="phone">
            <ElInput v-model.trim="editForm.phone" placeholder="请输入电话" />
          </ElFormItem>
          <ElFormItem label="邮箱" prop="email">
            <ElInput v-model.trim="editForm.email" placeholder="请输入邮箱" />
          </ElFormItem>
          <ElFormItem label="住址" prop="address">
            <ElInput v-model.trim="editForm.address" placeholder="请输入住址" />
          </ElFormItem>
        </ElForm>
      </div>
      <template #footer>
        <div class="dialog-footer">
          <div class="dialog-form-tips">
            <span class="star">*</span> 为必填项
          </div>
          <ElButton @click="dialogVisible = false">取消</ElButton>
          <ElButton
            type="primary"
            @click="submitHandle"
            :loading="submitLoading"
          >
            确定
          </ElButton>
        </div>
      </template>
    </ElDialog>

    <TextImport
      v-model="textImportVisible"
      v-model:classId="editForm.class_id"
      :class-list="classList"
      @submit="textImportSubmit"
    />

    <ExcelImport
      v-model="excelImportVisible"
      v-model:classId="editForm.class_id"
      :class-list="classList"
      @submit="excelImportSubmit"
    />
  </div>
</template>

<style scoped lang="scss">
.page-container {
  .tips {
    font-size: 14px;
    line-height: 1.5;
  }

  .stu-name {
    display: flex;
    align-items: center;
    gap: 2px;
  }

  .male,
  .female {
    font-size: 16px;
  }
  .male {
    color: #3b58e2;
  }

  .female {
    color: #ff5ebb;
  }

  .btn {
    padding: 0;
  }

  .add-class {
    color: #3b58e2;
  }

  .class-box {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;

    .title {
      flex-shrink: 0;
    }

    .class-select {
      width: 200px;
    }

    .el-button {
      margin-left: 0;
    }
  }

  .table-box {
    margin-top: 20px;
    overflow: hidden;
  }
}
</style>
